﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
using System.Collections.Generic;
using ManagedWinapi.Accessibility;

namespace WordAutomation
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private void MainForm_LocationChanged(object sender, EventArgs e)
        {
            AdjustFormLocation();
        }

        private void AdjustFormLocation()
        {
            var rec = Utils.GetWorkingArea();
            this.Top = rec.Top + rec.Height - this.Height;
            this.Left = rec.Left;
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
            AdjustFormSize();
        }

        private void AdjustFormSize()
        {
            Rectangle rec = Utils.GetWorkingArea();
            this.Width = rec.Width;
            MsWord.AdjustWindowPos();
        }

        [DllImport("user32")]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

        private void MainForm_Load(object sender, EventArgs e)
        {
            MsWord.LoadApplication();

            AdjustFormSize();
            AdjustFormLocation();

            var windowLong = Win32.GetWindowLong(MsWord.HWnd, Win32.GWL_STYLE);
            windowLong = (int)(windowLong & (~Win32.WS_THICKFRAME) & (~Win32.WS_MAXIMIZEBOX));
            var l = Win32.SetWindowLong(MsWord.HWnd, Win32.GWL_STYLE, windowLong);

            uint processId;
            uint threadId = GetWindowThreadProcessId(MsWord.HWnd, out processId);

            listener.ThreadId = (uint)threadId;
            listener.ProcessId = (uint)processId;
        }

        private Dictionary<String, int> time = new Dictionary<string, int>();

        private void listener_EventOccurred(object sender, AccessibleEventArgs e)
        {
            try
            {
                if (e.EventType == AccessibleEventType.EVENT_OBJECT_LOCATIONCHANGE && e.HWnd == IntPtr.Zero && e.ObjectID == (uint)AccessibleObjectID.OBJID_CURSOR) return;
                //if (e.HWnd != MsWord.HWnd) return;
                if (e.AccessibleObject == null) return;

                //if (e.HWnd != MsWord.HWnd) return;

                string s = "";
                SystemAccessibleObject obj = e.AccessibleObject;

                int lastTime;
                time.TryGetValue(obj.Name, out lastTime);

                switch (e.EventType)
                {
                    case AccessibleEventType.EVENT_OBJECT_VALUECHANGE:
                        if (obj.StateString != "None")
                            break;
                        if (lastTime == 0 || e.Time - lastTime > 200)
                        {
                            s = "Change " + obj.Name + " to " + 
                                obj.Value + " " + obj.StateString;
                            time[obj.Name] = (int)e.Time;
                        }
                        break;
                    case AccessibleEventType.EVENT_OBJECT_STATECHANGE:
                        switch (obj.RoleString)
                        {
                            case "push button":
                            case "split button":
                            case "check box":
                                if (obj.StateString.Contains("pressed") == false)
                                    break;

                                if (lastTime == 0 || e.Time - lastTime > 200)
                                {
                                    s = "Click " + obj.RoleString + " " + obj.Name +
                                        " " + obj.StateString + " " + obj.Value + ".";
                                    time[obj.Name] = (int)e.Time;
                                }
                                break;
                            default:
                                //s = obj.RoleString + " " + obj.Name;
                                break;
                        }
                        break;
                    case AccessibleEventType.EVENT_OBJECT_SELECTION:
                        s = "Select " + obj.Name + " " + obj.RoleString + " " + obj.StateString;
                        break;
                    default:
                        s = e.EventType.ToString();
                        break;
                }

                if (s.Length > 0)
                    listBox1.Items.Insert(0, s);
            }
            catch (Exception)
            {
            }
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            MsWord.Show();
        }

        private void btnHide_Click(object sender, EventArgs e)
        {
            MsWord.Hide();
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            MsWord.QuitApplication();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            listener.Enabled = !listener.Enabled;
        }
    }
}
